{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCKSGZ12A58A7CA4B</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCVTLJ12A6310F0FD</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SODLLYS12A8C13A96B</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOEGIYH12A6D4FC0E3</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOFRQTD12A81C233C0</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  play_count\n",
       "0  4e11f45d732f4861772b2906f81a7d384552ad12  SOCKSGZ12A58A7CA4B           1\n",
       "1  4e11f45d732f4861772b2906f81a7d384552ad12  SOCVTLJ12A6310F0FD           1\n",
       "2  4e11f45d732f4861772b2906f81a7d384552ad12  SODLLYS12A8C13A96B           3\n",
       "3  4e11f45d732f4861772b2906f81a7d384552ad12  SOEGIYH12A6D4FC0E3           1\n",
       "4  4e11f45d732f4861772b2906f81a7d384552ad12  SOFRQTD12A81C233C0           2"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "dpath = './data/'\n",
    "df=pd.read_csv(dpath +'triplet_dataset_sub.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 37519 entries, 0 to 37518\n",
      "Data columns (total 3 columns):\n",
      "user          37519 non-null object\n",
      "song          37519 non-null object\n",
      "play_count    37519 non-null int64\n",
      "dtypes: int64(1), object(2)\n",
      "memory usage: 879.5+ KB\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "790"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['user'].unique().shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "800"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['song'].unique().shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 获得显示打分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count_total_x</th>\n",
       "      <th>score</th>\n",
       "      <th>play_count_total_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCKSGZ12A58A7CA4B</td>\n",
       "      <td>259</td>\n",
       "      <td>0.003861</td>\n",
       "      <td>259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCVTLJ12A6310F0FD</td>\n",
       "      <td>259</td>\n",
       "      <td>0.003861</td>\n",
       "      <td>259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SODLLYS12A8C13A96B</td>\n",
       "      <td>259</td>\n",
       "      <td>0.011583</td>\n",
       "      <td>259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOEGIYH12A6D4FC0E3</td>\n",
       "      <td>259</td>\n",
       "      <td>0.003861</td>\n",
       "      <td>259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOFRQTD12A81C233C0</td>\n",
       "      <td>259</td>\n",
       "      <td>0.007722</td>\n",
       "      <td>259</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  \\\n",
       "0  4e11f45d732f4861772b2906f81a7d384552ad12  SOCKSGZ12A58A7CA4B   \n",
       "1  4e11f45d732f4861772b2906f81a7d384552ad12  SOCVTLJ12A6310F0FD   \n",
       "2  4e11f45d732f4861772b2906f81a7d384552ad12  SODLLYS12A8C13A96B   \n",
       "3  4e11f45d732f4861772b2906f81a7d384552ad12  SOEGIYH12A6D4FC0E3   \n",
       "4  4e11f45d732f4861772b2906f81a7d384552ad12  SOFRQTD12A81C233C0   \n",
       "\n",
       "   play_count_total_x     score  play_count_total_y  \n",
       "0                 259  0.003861                 259  \n",
       "1                 259  0.003861                 259  \n",
       "2                 259  0.011583                 259  \n",
       "3                 259  0.003861                 259  \n",
       "4                 259  0.007722                 259  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将用户听某首歌的频率转化为用户对歌曲的打分\n",
    "#将歌曲的播放次数按照不同用户分别求和\n",
    "play_count_sum = df[['user','play_count']].groupby('user').sum()\n",
    "\n",
    "#更改列名\n",
    "play_count_sum =play_count_sum.rename(columns = {'play_count':'play_count_total'})\n",
    "\n",
    "#将用户播放所有歌曲次数加入原始数据集中\n",
    "df = df.merge(play_count_sum,left_on='user',right_index= True)\n",
    "\n",
    "#用户对某歌曲评分 =用户播放某歌曲次数/用户播放所有歌曲数目\n",
    "df['score'] = df['play_count']/df['play_count_total']\n",
    "\n",
    "#丢弃不使用的列\n",
    "df=df.drop(['play_count','play_count_total'],axis=1)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1、 分离并保存数据\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#按照8:2的比例将原始数据分为训练集和测试集\n",
    "df_train,df_test = train_test_split(df,train_size = 0.8,random_state =42)\n",
    "\n",
    "#\\保存数据\n",
    "df_train.to_csv('triplet_dataset_sub_train.csv')\n",
    "df_test.to_csv('triplet_dataset_sub_test.csv')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(30015, 5)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(7504, 5)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获得训练数据集用户、歌曲表\n",
    "user_train_unique = df_train['user'].unique()\n",
    "item_train_unique = df_train['song'].unique()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:33: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n"
     ]
    }
   ],
   "source": [
    "star = time.clock()\n",
    "\n",
    "#初始化用户 歌曲索引表\n",
    "user_item_dict = {}\n",
    "\n",
    "#遍历每个用户\n",
    "for u in user_train_unique:\n",
    "    item_list = []\n",
    "    \n",
    "    #遍历此用户听过的所有歌曲\n",
    "\n",
    "#     print(df_train['user']==u)\n",
    "    for i in df_train[df_train['user']==u]['song']:\n",
    "        if i not in item_list:\n",
    "            item_list.append(i)\n",
    "    \n",
    "    user_item_dict[u] = item_list\n",
    "\n",
    "#初始化歌曲-用户索引表\n",
    "item_user_dict = {}\n",
    "\n",
    "#遍历每一首歌曲\n",
    "for i in item_train_unique:\n",
    "    user_list = []\n",
    "    \n",
    "    #遍历听过此歌曲的所有用户\n",
    "    for u in df_train[df_train['song']==i]['user']:\n",
    "        if u not in user_list:\n",
    "            user_list.append(u)\n",
    "            \n",
    "    item_user_dict[i] = user_list\n",
    "    \n",
    "end = time.clock()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.6197919999999986"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "end-star"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3建立训练集用户 - 歌曲打分表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "#初始化用户-歌曲的打分矩阵\n",
    "user_item_score = pd.DataFrame(index = user_train_unique,columns=item_train_unique)\n",
    "\n",
    "#遍历每一位用户\n",
    "for index in df_train.index:\n",
    "    user_item_score.loc[df_train.loc[index]['user']][df_train.loc[index]['song']] = df_train.loc[index]['score']\n",
    "    \n",
    "#user_item_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 建立测试集用户-歌曲索引表、用户-歌曲打分矩阵\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "#初始化测试集上用户-歌曲索引列表\n",
    "user_item_test_dict = {}\n",
    "\n",
    "#遍历测试集每一位用户\n",
    "for u in df_test['user'].unique():\n",
    "    item_list = []\n",
    "    \n",
    "    #遍历此用户听过的所有歌曲\n",
    "    \n",
    "    for i in df_test[df_test['user']==u]['song']:\n",
    "        if i not in item_list:\n",
    "            item_list.append(i)\n",
    "            \n",
    "    user_item_test_dict[u] = item_list\n",
    "    \n",
    "#初始化测试集上用户-歌曲打分矩阵\n",
    "user_item_test_score = pd.DataFrame(index = df_test['user'].unique(),columns= df_test['song'].unique())\n",
    "\n",
    "for index in df_test.index:\n",
    "    user_item_test_score.loc[df_test.loc[index]['user']][df_test.loc[index]['song']] = df_test.loc[index]['score']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 保存数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "\n",
    "#保存训练集用户-歌曲，歌曲-用户索引表,用户-歌曲打分矩阵\n",
    "pickle.dump(user_item_dict,open('user_item_dict.pkl','wb'))\n",
    "pickle.dump(item_user_dict,open('item_user_dict.pkl','wb'))\n",
    "pickle.dump(user_item_score,open('user_item_score.pkl','wb'))\n",
    "\n",
    "#保存测试集上用户-歌曲索引表、用户-歌曲的打分矩阵\n",
    "pickle.dump(user_item_test_dict,open('user_item_test_dict.pkl','wb'))\n",
    "pickle.dump(user_item_test_score,open('user_item_test_score.pkl','wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "78"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
